-
Notifications
You must be signed in to change notification settings - Fork 633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Future::boxed and Stream::boxed should prevent double boxing #512
Conversation
990539f
to
be4984a
Compare
|
src/stream/mod.rs
Outdated
@@ -250,7 +250,40 @@ pub trait Stream { | |||
fn boxed(self) -> BoxStream<Self::Item, Self::Error> | |||
where Self: Sized + Send + 'static, | |||
{ | |||
::std::boxed::Box::new(self) | |||
#[cfg(rust_at_least_1_18)] | |||
fn boxed<S>(stream: S) -> BoxStream<S::Item, S::Error> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems to be a fully copy/paste version of boxed()
for Future
except the result type itself. I'd rather decompose them both to a some type-parametrized function.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here I also tried to write generic version and couldn't.
src/future/mod.rs
Outdated
&mut r as *mut BoxFuture<F::Item, F::Error> as *mut u8 as *mut F, | ||
1); | ||
mem::forget(future); | ||
r |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we just return future
here without unsafe magic?
Understood.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, because compiler doesn't know that future
can be cast to BoxFuture<...>
. Moreover, even transmute
doesn't work, because compiler cannot prove that type sizes are equal.
OK, updated the PR with slightly more generic version. |
5d593ef
to
c1b5845
Compare
Are there measureable gains from this PR? I agree that theoretically this is a plausible optimization but I'd much rather prefer the solution in https://github.com/alexcrichton/futures-rs/pull/513/files |
I also fear that most users aren't actually using |
I've updated PR with synthetic test. Before this PR:
So, accidental additional unnecessary boxing adds significant overhead for simple streams. It is hard to say what's performance impact of accidental boxing in real applications. However, the problem is that from user point of view it is easier to simply use safe |
I also simply call About
|
Updated the PR with specialization instead of |
Yes I think it's obvious that this is a performance gain in microbenchmarks, but my worry is that this doesn't actually get exercised that much higher up the stack. I'm ok with the specialization approach but I would not want to land it until specialization is stable. I'm ok leaving this PR open, however. |
I would rather see |
FWIW I usually skip |
Currently I agree with @carllerche that we're highly likely to remove/deprecate |
Fixes #511
travis-ci also runs tests on rust 1.10. In rust 1.10
TypeId::of
requiresReflect
trait. I have not found an easy way to work around this limitation, so I decided to makeboxed
prevent double boxing only starting from rust 1.18 (which is latest stable at the moment). Some older version between 1.10 and 1.18 could be chosen for switch, but because travis-ci does not test these versions, I think it is reasonable to enable this behavior only from 1.18.